import { io, Socket } from 'socket.io-client'
import { useAuthStore } from '@/stores/auth'

/**
 * 团队协作Socket.IO连接管理器
 */
class TeamSocketManager {
  private socket: Socket | null = null
  private userId: number | null = null
  private reconnectAttempts = 0
  private maxReconnectAttempts = 5
  private isConnecting = false
  private heartbeatTimer: NodeJS.Timeout | null = null

  // 事件监听器映射
  private eventListeners: Map<string, Function[]> = new Map()
  
  // 连接状态回调
  private connectionStateCallbacks: Map<string, Function> = new Map()

  // 连接状态枚举
  public readonly ConnectionState = {
    DISCONNECTED: 'disconnected',
    CONNECTING: 'connecting',
    CONNECTED: 'connected',
    RECONNECTING: 'reconnecting',
    FAILED: 'failed'
  } as const

  private currentState: string = this.ConnectionState.DISCONNECTED

  /**
   * 连接到团队协作Socket.IO服务器
   */
  async connect(userId: number): Promise<void> {
    if (this.isConnecting || (this.socket && this.socket.connected)) {
      console.log('🔄 团队Socket连接已存在或正在连接中')
      return
    }

    this.isConnecting = true
    this.userId = userId
    this.setConnectionState(this.ConnectionState.CONNECTING)

    try {
      console.log('🚀 开始连接团队协作Socket.IO服务器...')

      this.socket = io('http://localhost:9092', {
        query: { 
          userId: userId.toString(),
          type: 'team' // 标识为团队协作连接
        },
        transports: ['websocket', 'polling'],
        timeout: 10000,
        reconnection: true,
        reconnectionAttempts: this.maxReconnectAttempts,
        reconnectionDelay: 1000,
        reconnectionDelayMax: 5000,
        maxReconnectionAttempts: this.maxReconnectAttempts
      })

      // 等待连接成功
      await new Promise<void>((resolve, reject) => {
        const timeout = setTimeout(() => {
          reject(new Error('连接超时'))
        }, 10000)

        // 先设置事件监听器
        this.socket!.on('team_connected', () => {
          console.log('🎉 收到team_connected事件')
          clearTimeout(timeout)
          resolve()
        })

        this.socket!.on('connect_error', (error) => {
          clearTimeout(timeout)
          reject(error)
        })

        this.socket!.on('connect', () => {
          console.log('✅ Socket.IO基础连接成功，等待team_connected确认...')
        })
      })

      // 连接成功后再设置其他事件监听器
      this.setupEventListeners()

      this.isConnecting = false
      this.reconnectAttempts = 0
      this.setConnectionState(this.ConnectionState.CONNECTED)
      this.startHeartbeat()

      console.log('✅ 团队协作Socket.IO连接成功')

    } catch (error) {
      this.isConnecting = false
      this.setConnectionState(this.ConnectionState.FAILED)
      console.error('❌ 团队协作Socket.IO连接失败:', error)
      throw error
    }
  }

  /**
   * 断开连接
   */
  disconnect(): void {
    if (this.socket) {
      this.socket.disconnect()
      this.socket = null
    }
    
    this.stopHeartbeat()
    this.userId = null
    this.isConnecting = false
    this.reconnectAttempts = 0
    this.setConnectionState(this.ConnectionState.DISCONNECTED)
    
    console.log('🔌 团队协作Socket.IO连接已断开')
  }

  /**
   * 设置事件监听器
   */
  private setupEventListeners(): void {
    if (!this.socket) return

    // 连接成功
    this.socket.on('connect', () => {
      console.log('✅ 团队Socket连接成功')
      this.setConnectionState(this.ConnectionState.CONNECTED)
      this.reconnectAttempts = 0
    })

    // 连接断开
    this.socket.on('disconnect', (reason) => {
      console.log('🔌 团队Socket连接断开:', reason)
      this.setConnectionState(this.ConnectionState.DISCONNECTED)
      this.stopHeartbeat()

      if (reason === 'io server disconnect') {
        // 服务器主动断开，尝试重连
        this.reconnect()
      }
    })

    // 连接错误
    this.socket.on('connect_error', (error) => {
      console.error('❌ 团队Socket连接错误:', error)
      this.setConnectionState(this.ConnectionState.FAILED)
      this.reconnect()
    })

    // 团队连接确认 (已在connect方法中处理，这里只处理后续的确认)
    this.socket.on('team_connected', (data) => {
      console.log('🎉 团队协作连接确认:', data)
      this.startHeartbeat()
    })

    // 错误处理
    this.socket.on('error', (error) => {
      console.error('❌ 团队Socket错误:', error)
      this.triggerEvent('error', error)
    })

    // 新团队消息
    this.socket.on('new_team_message', (message) => {
      console.log('📨 收到新团队消息:', message)
      this.triggerEvent('new_team_message', message)
    })

    // 消息发送确认
    this.socket.on('message_sent', (data) => {
      console.log('✅ 收到消息发送确认:', data)
      this.triggerEvent('message_sent', data)
    })

    // 团队在线成员
    this.socket.on('team_online_members', (data) => {
      console.log('👥 团队在线成员:', data)
      this.triggerEvent('team_online_members', data)
    })

    // 成员上线/下线状态
    this.socket.on('member_online_status', (data) => {
      console.log('🟢 成员在线状态变更:', data)
      this.triggerEvent('member_online_status', data)
    })

    // 成员加入团队
    this.socket.on('member_joined_team', (data) => {
      console.log('👋 成员加入团队:', data)
      this.triggerEvent('member_joined_team', data)
    })

    // 成员离开团队
    this.socket.on('member_left_team', (data) => {
      console.log('👋 成员离开团队:', data)
      this.triggerEvent('member_left_team', data)
    })

    // 加入团队确认
    this.socket.on('joined_team', (data) => {
      console.log('✅ 加入团队成功:', data)
      this.triggerEvent('joined_team', data)
    })
  }

  /**
   * 重连逻辑
   */
  private reconnect(): void {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('❌ 团队Socket重连次数超限，停止重连')
      this.setConnectionState(this.ConnectionState.FAILED)
      return
    }

    this.reconnectAttempts++
    this.setConnectionState(this.ConnectionState.RECONNECTING)
    
    const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts - 1), 30000)
    console.log(`🔄 团队Socket第${this.reconnectAttempts}次重连，${delay}ms后开始...`)

    setTimeout(() => {
      if (this.userId) {
        this.connect(this.userId).catch(error => {
          console.error('❌ 团队Socket重连失败:', error)
        })
      }
    }, delay)
  }

  /**
   * 开始心跳检测
   */
  private startHeartbeat(): void {
    this.stopHeartbeat()
    this.heartbeatTimer = setInterval(() => {
      if (this.socket && this.socket.connected) {
        this.socket.emit('ping')
      }
    }, 25000) // 25秒心跳
  }

  /**
   * 停止心跳检测
   */
  private stopHeartbeat(): void {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer)
      this.heartbeatTimer = null
    }
  }

  /**
   * 设置连接状态并通知监听器
   */
  private setConnectionState(state: string): void {
    if (this.currentState !== state) {
      this.currentState = state
      console.log(`🔄 团队Socket连接状态变更: ${state}`)

      // 通知所有监听器
      this.connectionStateCallbacks.forEach(callback => {
        try {
          callback(state, this.reconnectAttempts)
        } catch (error) {
          console.error('连接状态回调执行失败:', error)
        }
      })
    }
  }

  /**
   * 监听连接状态变化
   */
  onConnectionStateChange(id: string, callback: Function): void {
    this.connectionStateCallbacks.set(id, callback)
  }

  /**
   * 移除连接状态监听器
   */
  offConnectionStateChange(id: string): void {
    this.connectionStateCallbacks.delete(id)
  }

  /**
   * 监听事件
   */
  on(eventName: string, callback: Function): void {
    if (!this.eventListeners.has(eventName)) {
      this.eventListeners.set(eventName, [])
    }
    this.eventListeners.get(eventName)!.push(callback)
  }

  /**
   * 移除事件监听器
   */
  off(eventName: string, callback?: Function): void {
    if (!callback) {
      this.eventListeners.delete(eventName)
      return
    }

    const listeners = this.eventListeners.get(eventName)
    if (listeners) {
      const index = listeners.indexOf(callback)
      if (index > -1) {
        listeners.splice(index, 1)
      }
    }
  }

  /**
   * 触发事件
   */
  private triggerEvent(eventName: string, data: any): void {
    const listeners = this.eventListeners.get(eventName)
    if (listeners) {
      listeners.forEach(callback => {
        try {
          callback(data)
        } catch (error) {
          console.error(`事件监听器执行失败 [${eventName}]:`, error)
        }
      })
    }
  }

  /**
   * 发送团队消息（支持加密）
   */
  sendTeamMessage(teamId: number, content: string, messageType: string = 'text', fileInfo?: any): void {
    if (!this.socket || !this.socket.connected) {
      console.error('❌ 团队Socket未连接，无法发送消息')
      return
    }

    const messageData: any = {
      teamId,
      content,
      messageType
    }

    // 添加文件信息和加密信息
    if (fileInfo) {
      messageData.fileName = fileInfo.fileName
      messageData.fileSize = fileInfo.fileSize
      messageData.fileUrl = fileInfo.fileUrl

      // 添加加密相关字段
      if (fileInfo.iv) {
        messageData.iv = fileInfo.iv
      }
      if (fileInfo.encryptionAlgorithm) {
        messageData.encryptionAlgorithm = fileInfo.encryptionAlgorithm
      }
      if (fileInfo.keyVersion) {
        messageData.keyVersion = fileInfo.keyVersion
      }
      if (fileInfo.isEncrypted !== undefined) {
        messageData.isEncrypted = fileInfo.isEncrypted
      }
    }

    console.log('📤 发送团队消息:', {
      teamId,
      messageType,
      isEncrypted: messageData.isEncrypted,
      hasIV: !!messageData.iv
    })

    this.socket.emit('send_team_message', messageData)
  }

  /**
   * 发送事件
   */
  emit(eventName: string, data: any): void {
    if (!this.socket || !this.socket.connected) {
      console.error('❌ 团队Socket未连接，无法发送事件')
      return
    }

    this.socket.emit(eventName, data)
  }

  /**
   * 加入团队房间
   */
  joinTeam(teamId: number): void {
    if (!this.socket || !this.socket.connected) {
      console.error('❌ 团队Socket未连接，无法加入团队')
      return
    }

    this.socket.emit('join_team', { teamId })
  }

  /**
   * 离开团队房间
   */
  leaveTeam(teamId: number): void {
    if (!this.socket || !this.socket.connected) {
      console.error('❌ 团队Socket未连接，无法离开团队')
      return
    }

    this.socket.emit('leave_team', { teamId })
  }

  /**
   * 获取团队在线成员
   */
  getTeamOnlineMembers(teamId: number): void {
    if (!this.socket || !this.socket.connected) {
      console.error('❌ 团队Socket未连接，无法获取在线成员')
      return
    }

    this.socket.emit('get_team_online_members', { teamId })
  }

  /**
   * 获取连接状态
   */
  getConnectionState(): string {
    return this.currentState
  }

  /**
   * 检查是否已连接
   */
  isConnected(): boolean {
    const connected = this.socket !== null && this.socket.connected
    console.log(`🔍 Socket连接状态检查: socket=${this.socket !== null}, connected=${this.socket?.connected}, result=${connected}`)
    return connected
  }
}

// 创建单例实例
export const teamSocketManager = new TeamSocketManager()
export default teamSocketManager
